package com.example.agboxdemo.controller;

import cn.hutool.core.lang.Pair;
import cn.hutool.core.map.MapUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.agboxdemo.entity.po.UserCar;
import com.example.agboxdemo.entity.service.IUserCarService;
import com.example.agboxdemo.entity.vo.ResultVO;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicReference;

/**
 * @author hnn
 * @version 1.0
 * @date 2025-07-07 15:07
 */
@Slf4j
@RequiredArgsConstructor
@RestController
public class ShareCarController {

    public static long count = 0;

    private final ObjectMapper objectMapper;
    private final IUserCarService userCarService;

    private final Map<Integer, String> getPlateColorCodeMap = MapUtil.of(
            Pair.of(1, "未知"),
            Pair.of(2, "蓝色"),
            Pair.of(3, "黄色"),
            Pair.of(4, "白色"),
            Pair.of(5, "黑色"),
            Pair.of(6, "绿色")
    );

    private final Map<Integer, String> getPlateTypeCodeMap = MapUtil.of(
            Pair.of(1, "普通蓝牌"),
            Pair.of(2, "普通黑牌"),
            Pair.of(3, "普通黄牌"),
            Pair.of(4, "双层黄牌"),
            Pair.of(5, "教练车牌"),
            Pair.of(6, "警车车牌"),
            Pair.of(7, "新式武警车牌"),
            Pair.of(8, "新式军牌"),
            Pair.of(9, "大使馆车牌"),
            Pair.of(10, "新能源车牌"),
            Pair.of(11, "其它车牌")
    );

    private final Map<Integer, String> getCarTypeCodeMap = MapUtil.of(
            Pair.of(1, "住户车辆"),
            Pair.of(2, "租户车辆"),
            Pair.of(3, "亲情车辆"),
            Pair.of(4, "服务车辆"),
            Pair.of(5, "访客车辆"),
            Pair.of(6, "快递车辆"),
            Pair.of(7, "外卖车辆"),
            Pair.of(8, "小区服务车辆"),
            Pair.of(9, "小区工作车辆"),
            Pair.of(10, "其它车辆")
    );

    @PostMapping("/share/car")
    public ResultVO work(@RequestParam("key") String key, @RequestParam("json") String json) {
        log.info("recv key:{},json:{}", key, json);
        ObjectNode on = objectMapper.createObjectNode();
        try {
            JsonNode jsonNode = objectMapper.readTree(json);
            String method = jsonNode.get("method").asText();
            JsonNode params = jsonNode.get("params");
            switch (method) {
                case "getPlateInfo":
                    log.info("getPlateInfo params:{}", params);
                    AtomicReference<ObjectNode> onRef = new AtomicReference<>(on);
                    Optional.ofNullable(userCarService.getByPlate(params.get("plateNo").asText(), params.get("plateTypeCode").asInt()))
                            .ifPresent(userCar -> {
                                onRef.set(objectMapper.valueToTree(userCar));
                            });
                    on = onRef.get();
                    break;
                case "getPlateTypeCode":
                    log.info("getPlateTypeCode params:{}", params);
                    ArrayNode an = objectMapper.createArrayNode();
                    getPlateTypeCodeMap.forEach((k, v) -> {
                        an.addObject()
                                .put("code", k)
                                .put("name", v);
                    });
                    on.set("plateType", an);
                    break;
                case "getCarTypeCode":
                    log.info("getCarTypeCode params:{}", params);
                    ArrayNode an2 = objectMapper.createArrayNode();
                    getCarTypeCodeMap.forEach((k, v) -> {
                        an2.addObject()
                                .put("code", k)
                                .put("name", v);
                    });
                    on.set("carType", an2);
                    break;
                case "getPlateColorCode":
                    log.info("getPlateColorCode params:{}", params);
                    ArrayNode an3 = objectMapper.createArrayNode();
                    getPlateColorCodeMap.forEach((k, v) -> {
                        an3.addObject()
                                .put("code", k)
                                .put("name", v);
                    });
                    on.set("plateColor", an3);
                    break;
                case "getPlate":
                    log.info("getPlate params:{}", params);
                    Page<UserCar> page = new Page<>(params.get("page").asInt(), params.get("pageSize").asInt());
                    UserCar userQuery = objectMapper.treeToValue(params, UserCar.class);
                    userCarService.page(page, Wrappers.lambdaQuery(UserCar.class)
                            .eq(userQuery.getCredentialType() != null, UserCar::getCredentialType, userQuery.getCredentialType())
                            .eq(userQuery.getCredentialNo() != null, UserCar::getCredentialNo, userQuery.getCredentialNo())
                            .eq(userQuery.getEnabled() != null, UserCar::getEnabled, userQuery.getEnabled())
                    );
                    on.put("page", page.getCurrent());
                    on.put("page_size", page.getSize());
                    on.put("total_page", (int) Math.ceil((double) page.getTotal() / page.getSize()));
                    on.put("count", page.getTotal());
                    on.set("plateList", objectMapper.valueToTree(page.getRecords()));
                    break;
                case "updatePlate":
                    log.info("updatePlate params:{}", params);
                    UserCar userCar = new UserCar();
                    userCar.setPlateNo(params.get("plateNo").asText());
                    userCar.setPlateTypeCode(params.get("plateTypeCode").asInt());
                    userCar.setCarTypeCode(params.get("carTypeCode").asInt());
                    userCar.setCredentialType(params.get("credentialType").asInt());
                    userCar.setCredentialNo(params.get("credentialNo").asText());
                    userCar.setEnabled(params.get("enabled").asBoolean());
                    boolean isOk = userCarService.updateByCredential(userCar);
                    return new ResultVO(isOk ? "success" : "error");
            }
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }

//        on.put("datetime", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        return new ResultVO<>(on);
    }
}
